#include <stdlib.h>
#include <stdio.h>

#define uc unsigned char

typedef struct {
	uc r, g, b;
} pixel;

int main (int argc, char ** argv) 
{ 
	struct timeval start_total, end_total;
	struct timeval start_seq, end_seq;
	gettimeofday(&start_total, NULL);

	// require arguments to run
	if( argc != 3 ) {
		printf("usage: ./io_test <file_input_name.ppm> <file_output_name.ppm>\n");
		exit(1);
	}

	// open file
	FILE * fp = fopen(argv[1], "r");
	FILE * fout = fopen(argv[2], "w");
	char encoding[4];
	int ncol, nrow;
	uc maxValue;
	int i, j;

	// read file header
	fscanf(fp, "%s", encoding);
	fscanf(fp, "%d %d", &ncol, &nrow);
	fscanf(fp, "%hhu", &maxValue);

	gettimeofday(&start_seq, NULL);

	// alloc memory for both matrices
	pixel ** in = (pixel **) malloc ( nrow * sizeof (pixel *) );
	pixel ** out = (pixel **) malloc ( nrow * sizeof (pixel *) );
	for(i = 0; i < nrow; i++) {
		in[i] = (pixel *) malloc ( ncol * sizeof (pixel ) );
		out[i] = (pixel *) malloc ( ncol * sizeof (pixel ) );
	}

	gettimeofday(&end_seq, NULL);

	// read image
	for(i = 0; i < nrow; i++) {
		for(j = 0; j < ncol; j++) {
			fscanf(fp, "%hhu %hhu %hhu", &in[i][j].r, &in[i][j].g, &in[i][j].b);
			out[i][j].r = in[i][j].r;
			out[i][j].g = in[i][j].g;
			out[i][j].b = in[i][j].b;
		}
	}

	// write the results in output file
	fprintf(fout, "%s\n", encoding);
	fprintf(fout, "%d %d\n", ncol, nrow);
	fprintf(fout, "%hhu\n", maxValue);
	for(i = 0; i < nrow; i++) {
		for(j = 0; j < ncol; j++) 
			fprintf(fout, "%hhu %hhu %hhu ", out[i][j].r, out[i][j].g, out[i][j].b);
		fprintf(fout, "\n");
	}

	// free memory
	for(i = 0; i < nrow; i++)
		free(in[i]), free(out[i]);
	free(in);
	free(out);
	fclose(fp);
	fclose(fout);

	gettimeofday(&end_total, NULL);

	double result_total = end_total.tv_sec - start_total.tv_sec + (end_total.tv_usec - start_total.tv_usec) / 1000000.0;
	//printf("Sequential processing + I/O - TOTAL : %lfs\n", result_total);

	return 0;
}
